/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package exmtgproj;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

/**
 *
 * @author marcus ahlen
 */
public class CardList extends ArrayList<Card> implements Statics, Serializable {

    static final int NAME = 0;
    static final int TYPE = 1;
    static final int SUBTYPE = 2;
    static final int COLOR = 3;
    static final int RARITY = 4;
    static final int COST = 5;
    static final int FACEDOWN = 6;
    static final int MARKED = 7;
    static final String[] sort = {"Name", "Type", "Subtype", "Color", "Rarity", "Converted Manacost", "Facedown", "Marked"};
    String name = "";

    /**
     * blandar kort listan
     */
    public void shuffle() {
        Collections.shuffle(this);
    }

    /**
     * Söker efter ett kort i listan
     * @param s namn på kortet som skall sökas efter
     * @return kortet
     */
    public Card search(String s) {
        boolean exact = s.contains("\"");   //om ett " finns i söktexten, sök efter den exakta frasen TODO fixa bättre sätt
        s = s.replace("\"", "");
        if (exact) {
            for (Card c : this) {
                if (c.name.toLowerCase().equals(s)) {
                    return c;
                }
            }
        } else {
            for (Card c : this) {
                if (c.name.toLowerCase().contains(s)) {
                    return c;
                }
            }
        }

        return null;
    }

    /**
     * sorterar kort listan efter namn, typ, färg, raritet, och/eller manakostnad
     * @param by
     */
    public void sort(ArrayList<String> by) {
        String[] s = new String[by.size()];
        for (int i = 0; i < by.size(); i++) {
            s[i] = by.get(i);
        }
        sort(s);
    }

    /**
     * sorterar kort listan efter namn, typ, färg, raritet, och/eller manakostnad
     * @param by bestämmer på vilket sätt listan ska bli sorterad på, ska ändast innehålla Strings som finns med i variabeln sort
     */
    public void sort(final String... by) {
        Collections.sort(this, new Comparator() {

            public int compare(Object o1, Object o2) {
                Card c1 = (Card) o1;
                Card c2 = (Card) o2;
                int res = 0;
                for (int i = 0; i < by.length; i++) {
                    res = compare(c1, c2, i);
                    if (res != 0) {
                        break;
                    }
                }
                return res;
            }

            private int compare(Card c1, Card c2, int lev) {
                if (by.length <= lev) {
                    return 0;
                }
                if (by[lev].equals(sort[NAME])) {
                    return c1.name.compareToIgnoreCase(c2.name);
                } else if (by[lev].equals(sort[TYPE])) {
                    for (int i = 0; i < TYPES; i++) {
                        if (c1.type[i] && !c2.type[i]) {
                            return -1;
                        } else if (!c1.type[i] && c2.type[i]) {
                            return 1;
                        }
                    }
                    return 0;
                } else if (by[lev].equals(sort[SUBTYPE])) {
                    String s1 = "";
                    String s2 = "";
                    for (int i = 0; i < c1.subtype.size(); i++) {
                        s1 += c1.subtype.get(i) + " ";
                    }
                    for (int i = 0; i < c2.subtype.size(); i++) {
                        s2 += c2.subtype.get(i) + " ";
                    }
                    return s1.compareToIgnoreCase(s2);
                } else if (by[lev].equals(sort[COLOR])) {
                    int i1 = 0;
                    int i2 = 0;
                    for (int i = 1; i < COLORS; i++) {
                        if (c1.color[i]) {
                            //Math.pow(2, COLORS - 1) 'r bara ett stort tal som g;r att korten delas upp efter hur m[nga olika f'rger de har
                            i1 += Math.pow(2, i - 1) + Math.pow(2, COLORS);
                        }
                        if (c2.color[i]) {
                            i2 += Math.pow(2, i - 1) + Math.pow(2, COLORS);
                        }
                    }
                    return i1 - i2;
                } else if (by[lev].equals(sort[RARITY])) {
                    return c1.getRarityValue() - c2.getRarityValue();
                } else if (by[lev].equals(sort[COST])) {
                    int i1 = 0;
                    int i2 = 0;
                    for (int i = 0; i < COLORS; i++) {
                        i1 += c1.cast.cost[i];
                        i2 += c2.cast.cost[i];
                    }
                    return i1 - i2;
                } else if (by[lev].equals(sort[FACEDOWN])) {
                    if (c1.facedown && !c2.facedown) {
                        return 1;
                    }
                    return 0;
                } else if (by[lev].equals(sort[MARKED])) {
                    if (c1.marked && !c2.marked) {
                        return 1;
                    }
                    return 0;
                }
                return 0;
            }
        });
    }

    void add(CardList cl) {
        for (Card c : cl) {
            add(c);
        }
    }

    public String toString() {
        return name;
    }
}

